<template>
    <div>
        <el-table v-loading="vLoading" :data="data" :height="bodySize.height-subHeight" border :show-header="showHeader" ref="elTable" :highlight-current-row="highlightCurrentRow"
            :show-summary="showSummary" :summary-method="getSummaryMethod" @row-dblclick="rowdblClick" @row-click="rowClick" @row-contextmenu="rowContextmenu" @selection-change="selectionChange"
            :row-class-name="rowClassName">
            <el-table-column type="selection" width="40" v-if="checkBox"></el-table-column>
            <el-table-column type="index" label="序号" v-if="showIndex" :index="CalcTableIndex(paginate)" width="80">
                <template #header>
                    <div v-if="selectTableRow" class="p-table-clear-select" @click="clearSelectTtable">取消选中</div>
                    <div v-else>序号</div>
                </template>
            </el-table-column>
            <slot></slot>
        </el-table>
        <div style="height:10px;" v-if="showPaginate"></div>
        <p-pagination v-if="showPaginate" v-model="paginate" @change="paginateChange"></p-pagination>
    </div>
</template>

<script lang="ts">
import {
    defineComponent,
    nextTick,
    onMounted,
    reactive,
    ref,
    toRefs,
    watch,
} from "vue";
import { useStore } from "vuex";
import { IPaginate, defaultPaginate, CalcTableIndex } from "@/lib/IApp";
import PPagination from "@/components/PPagination.vue";
/**
 * state 数据类型
 */
interface IState {
    /**
     * 分页对象
     */
    paginate: IPaginate;
    selectTableRow: any;
}

export default defineComponent({
    name: "PTable",
    props: {
        modelValue: {
            type: Object,
            default: () => defaultPaginate,
        },
        // 是否显示加载状态
        vLoading: {
            type: Boolean,
            default: false,
        },
        // 是否显示表头
        showHeader: {
            type: Boolean,
            default: true,
        },
        // 是否显示 分页工具
        showPaginate: {
            type: Boolean,
            default: true,
        },
        // 是否显示 选择框
        checkBox: {
            type: Boolean,
            default: true,
        },
        // 是否显示 序号
        showIndex: {
            type: Boolean,
            default: true,
        },
        // 是否默认选择第 N行
        selectIndex: {
            type: Number,
            default: 0,
        },
        // 当前是否是 选择状态
        select: {
            type: Boolean,
        },
        // 是否高亮行
        highlightCurrentRow: {
            type: Boolean,
            default: true,
        },
        // 数据列表
        data: {
            type: Array,
            default: () => [],
        },
        //  表格高度=窗口高度 - subHeight
        subHeight: {
            type: Number,
            default: 0,
        },
        // 行的 className 的回调方法，也可以使用字符串
        rowClassName: {
            type: Function,
            default: () => () => false,
        },
        // 显示合计字段的索引
        showSummaryIndex: {
            type: Number,
            default: 0,
        },
        // 显示合计字段的标题
        showSummaryTitle: {
            type: String,
            default: "合计",
        },
        // 是否显示合计
        showSummary: {
            type: Boolean,
            default: false,
        },
        // 合计自定义方法
        summaryMethod: {
            type: Function,
            default: () => (key: any, index: number, data: any[]) => false,
        },
    },
    components: { PPagination },
    emits: ["row-click", "paginate", "row-dblclick", "row-clear", "selection-change"],
    setup(props, { emit }) {
        const store = useStore();
        const { UIAuth, bodySize } = toRefs(store.state);
        const elTable: any = ref<any>();
        const state = reactive<IState>({
            paginate: defaultPaginate,
            selectTableRow: null,
        });
        watch(
            () => props.modelValue,
            (val) => {
                state.paginate = val as IPaginate;
            }
        );
        watch(
            () => props.data,
            (val) => {
                if (props.selectIndex > 0 && val.length >= props.selectIndex) {
                    nextTick(() => {
                        state.selectTableRow = val[props.selectIndex - 1];
                        elTable.value.setCurrentRow(state.selectTableRow);
                        emit("row-click", {
                            row: state.selectTableRow,
                            column: {},
                        });
                    });
                }
            }
        );
        onMounted(() => {
            state.paginate = props.modelValue as IPaginate;
        });
        /**
         * 清除选择
         */
        const clearSelect = () => {
            state.selectTableRow = null;
            elTable.value.setCurrentRow();
        };
        /**
         * 选中页码回调
         */
        const paginateChange = () => {
            emit("paginate", state.paginate);
        };
        /**
         * 当某一行被点击时会触发该事件
         */
        const rowClick = (row: any, column: any, event: MouseEvent) => {
            if (props.highlightCurrentRow) {
                state.selectTableRow = row;
            }
            emit("row-click", { row, column, event });
        };
        /**
         * 当某一行被双击时会触发该事件
         */
        const rowdblClick = (row: any, column: any, event: MouseEvent) => {
            emit("row-dblclick", { row, column, event });
        };
        /**
         * 取消选中行
         */

        const clearSelectTtable = () => {
            state.selectTableRow = null;
            elTable.value.setCurrentRow();
            emit("row-clear");
        };
        /**
         * 当某一行被鼠标右键点击时会触发该事件
         */
        const rowContextmenu = (row: any, column: any, event: MouseEvent) => {
            clearSelectTtable();
        };
        // 多选是触发

        function selectionChange(val: any[]) {
            emit("selection-change", val);
        }
        /**
         * 自定义合计方法
         */
        const getSummaryMethod = (param: any) => {
            const { columns, data } = param;
            const sums: any[] = [];
            columns.forEach((column: any, index: number) => {
                if (index === props.showSummaryIndex) {
                    sums[index] = props.showSummaryTitle;
                    return;
                }
                const sum: any = props.summaryMethod(
                    column.property,
                    index,
                    data
                );
                if (sum) {
                    sums[index] = sum;
                }
            });
            return sums;
        };
        return {
            UIAuth,
            bodySize,
            CalcTableIndex,
            ...toRefs(state),
            paginateChange,
            elTable,
            clearSelect,
            rowClick,
            rowdblClick,
            rowContextmenu,
            clearSelectTtable,
            getSummaryMethod,
            selectionChange
        };
    },
});
</script>

<style scoped lang="scss">
.p-table-clear-select {
    color: $primary-color;
    cursor: pointer;
    &:hover {
        color: $primary-color-active;
    }
}
</style>